package com.suncky.frame.http;

import android.text.TextUtils;

import androidx.annotation.NonNull;

import com.suncky.frame.http.config.IOkHttpConfig;
import com.suncky.frame.utils.CollectionUtils;

import java.lang.ref.WeakReference;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;

import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import retrofit2.Converter;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;

public class HttpWrapper {

    private IOkHttpConfig mConfig;
    private OkHttpClient mOkHttpClient;
    private Retrofit mRetrofit;

    private HashMap<String, WeakReference<Retrofit>> mRetrofitMap;

    private HttpWrapper() {
    }

    public void init(@NonNull IOkHttpConfig config) {
        mConfig = config;
        initOkHttpClient();
        initRetrofit();
    }

    private void initOkHttpClient() {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();
        if (mConfig.getCache() != null) {
            builder.cache(mConfig.getCache());
        }
        if (!CollectionUtils.isEmpty(mConfig.getInterceptors())) {
            for (Interceptor i : mConfig.getInterceptors()) {
                builder.addInterceptor(i);
            }
        }
        if (!CollectionUtils.isEmpty(mConfig.getNetworkInterceptors())) {
            for (Interceptor i : mConfig.getNetworkInterceptors()) {
                builder.addNetworkInterceptor(i);
            }
        }
        if (mConfig.getCookieJar() != null) {
            builder.cookieJar(mConfig.getCookieJar());
        }
        if (mConfig.getConnectOutTime() > 0) {
            builder.connectTimeout(mConfig.getConnectOutTime(), TimeUnit.SECONDS);
        }
        if (mConfig.getWriteOutTime() > 0) {
            builder.writeTimeout(mConfig.getWriteOutTime(), TimeUnit.SECONDS);
        }
        if (mConfig.getReadOutTime() > 0) {
            builder.readTimeout(mConfig.getReadOutTime(), TimeUnit.SECONDS);
        }
        mOkHttpClient = builder.build();
    }

    /**
     * retrofit默认连接配置，连接超时15秒,读取超时20秒,没有写入超时
     */
    private void initRetrofit() {
        Retrofit.Builder mBuilder = new Retrofit.Builder();
        mBuilder.client(mOkHttpClient);
        mBuilder.baseUrl(mConfig.getBaseUrl());
        if (!CollectionUtils.isEmpty(mConfig.getConverter())) {
            for (Converter.Factory c : mConfig.getConverter()) {
                mBuilder.addConverterFactory(c);
            }
        }
        mBuilder.addCallAdapterFactory(RxJava2CallAdapterFactory.create());
        mRetrofit = mBuilder.build();
    }

    private static final class HttpWrapperHolder {
        static final HttpWrapper sInstance = new HttpWrapper();
    }

    public static HttpWrapper getInstance() {
        return HttpWrapperHolder.sInstance;
    }

    public Retrofit getRetrofit() {
        return mRetrofit;
    }

    public Retrofit getRetrofit(String baseUrl) {
        if (TextUtils.equals(baseUrl, mConfig.getBaseUrl())) {
            return mRetrofit;
        }
        if (mRetrofitMap == null) {
            mRetrofitMap = new HashMap<>();
        }
        Retrofit retrofit = null;
        if (mRetrofitMap.get(baseUrl) != null) {
            retrofit = mRetrofitMap.get(baseUrl).get();
        }
        if (retrofit == null) {
            retrofit = generateRetrofitWithBaseUrl(baseUrl);
            mRetrofitMap.put(baseUrl, new WeakReference<>(retrofit));
        }
        return retrofit;
    }

    private Retrofit generateRetrofitWithBaseUrl(String baseUrl) {
        if (TextUtils.isEmpty(baseUrl)) {
            return null;
        }
        Retrofit.Builder builder = new Retrofit.Builder();
        builder.client(mOkHttpClient);
        builder.baseUrl(baseUrl);
        if (!CollectionUtils.isEmpty(mConfig.getConverter())) {
            for (Converter.Factory c : mConfig.getConverter()) {
                builder.addConverterFactory(c);
            }
        }
        builder.addCallAdapterFactory(RxJava2CallAdapterFactory.create());
        return builder.build();
    }
}
